package com.igroupes.ovineherd.raw.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.igroupes.ovineherd.constant.CacheName;
import com.igroupes.ovineherd.constant.Constants;
import com.igroupes.ovineherd.dto.ModelOrder;
import com.igroupes.ovineherd.dto.UserInfo;
import com.igroupes.ovineherd.dto.response.Meta;
import com.igroupes.ovineherd.dto.response.ModelDataJsonListResponse;
import com.igroupes.ovineherd.entity.DataModelAttributeEntity;
import com.igroupes.ovineherd.entity.DataModelRelationshipEntity;
import com.igroupes.ovineherd.entity.DataModelTableEntity;
import com.igroupes.ovineherd.entity.DataModelVersionEntity;
import com.igroupes.ovineherd.enums.BooleanKey;
import com.igroupes.ovineherd.exception.ModelException;
import com.igroupes.ovineherd.model.IParentModelData;
import com.igroupes.ovineherd.model.ModelData;
import com.igroupes.ovineherd.model.attribute.BasicAttribute;
import com.igroupes.ovineherd.dto.request.ModelOrderRequest;
import com.igroupes.ovineherd.model.dto.ModelVersionResponse;
import com.igroupes.ovineherd.model.dto.ModelDataAddRequest;
import com.igroupes.ovineherd.model.enums.BeanTypeKey;
import com.igroupes.ovineherd.model.enums.SqlFieldKey;
import com.igroupes.ovineherd.model.table.TableAttribute;
import com.igroupes.ovineherd.query.*;
import com.igroupes.ovineherd.raw.service.IModelService;
import com.igroupes.ovineherd.raw.service.raw.DataModelAttributeService;
import com.igroupes.ovineherd.raw.service.raw.DataModelRelationshipService;
import com.igroupes.ovineherd.raw.service.raw.DataModelTableService;
import com.igroupes.ovineherd.raw.service.raw.DataModelVersionService;
import com.igroupes.ovineherd.util.DateUtils;
import com.igroupes.ovineherd.util.Requires;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.SystemException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ModelServiceImpl implements IModelService {
    @Autowired
    private DataModelTableService dataModelTableService;
    @Autowired
    private DataModelAttributeService dataModelAttributeService;
    @Autowired
    private DataModelRelationshipService dataModelRelationshipService;
    @Autowired
    private DataModelVersionService dataModelVersionService;
    @Autowired
    private ModelData modelData;

    @Override
    @Cacheable(value = CacheName.DATA_MODEL, key = "'template'", unless = "#result != null")
    public ModelData getFieldTemplate() {
        return modelData;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean modelAdd(ModelDataAddRequest modelDataAddRequest,Long userId) {
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        log.debug("数据请求参数=>{}", JSON.toJSONString(modelDataAddRequest));
        //1.分类校验参数
        //校验传值
        verifyModelDataAddRequest(modelDataAddRequest);

        TableFieldQuery tableFieldQuery = TableAttribute.sqlTable(modelDataAddRequest.getTable(),null);
        DataModelTableEntity dataModelTableEntity = tableFieldQuery.getDataModelTableEntity();
        // appId暂时使用userId代替
        dataModelTableEntity.setAddUser(userId);
        dataModelTableEntity.setVersionId(versionId);
        dataModelTableEntity.setStatus(DataModelTableEntity.ADD);
        //执行sql,返回id
        dataModelTableService.save(dataModelTableEntity);
        List<DataModelAttributeEntity> dataModelAttributeEntityList = new ArrayList<>();
        DataModelAttributeEntity dataModelAttributeIDEntity = new DataModelAttributeEntity(dataModelTableEntity.getId(), "编号", "id", versionId);
        dataModelAttributeIDEntity.setAddUser(userId);
        dataModelAttributeEntityList.add(dataModelAttributeIDEntity);
        //2.创建sql
        List<FieldQuery> fieldQueries = tableFieldQuery.getFieldList();
        for (FieldQuery fieldQuery :
                fieldQueries) {
            DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
            if (dataModelAttributeEntity != null) {
                dataModelAttributeEntity.setTableId(dataModelTableEntity.getId());
                dataModelAttributeEntity.setAddUser(userId);
                dataModelAttributeEntity.setVersionId(versionId);
                dataModelAttributeEntityList.add(dataModelAttributeEntity);
            }
        }
        if(modelDataAddRequest.getFields() != null && 0 != modelDataAddRequest.getFields().size()){
            for (IParentModelData parentModelData :
                    modelDataAddRequest.getFields()) {
                try {
                    BasicAttribute basicAttribute = getByBeanType(parentModelData.getBeanType());
                    List<FieldQuery> fieldQueries1 =  basicAttribute.sqlField(parentModelData,null);
                    fieldQueries.addAll(fieldQueries1);
                    for (FieldQuery fieldQuery :
                            fieldQueries1) {
                        DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                        dataModelAttributeEntity.setTableId(dataModelTableEntity.getId());
                        dataModelAttributeEntity.setAddUser(userId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntityList.add(dataModelAttributeEntity);
                    }
                } catch (ClassNotFoundException e) {
                    log.error("json未获得beanType，{}", e);
                    throw new ModelException("json未获得beanType值，" + parentModelData);
                }
            }

        }

        dataModelAttributeService.saveBatch(dataModelAttributeEntityList);
        tableFieldQuery.setFieldList(fieldQueries);
        //执行sql
        dataModelTableService.createTable(tableFieldQuery);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }


    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean modelDelete(Long tableId, Long userId) {
        Requires.requireNonNull(tableId, "参数不能为空!");
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        dataModelTableService.removeById(tableId);
        UpdateWrapper<DataModelAttributeEntity> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .set(DataModelAttributeEntity::getIsDel, System.currentTimeMillis())
                .eq(DataModelAttributeEntity::getVersionId, versionId)
                .eq(DataModelAttributeEntity::getTableId, tableId);
        dataModelAttributeService.update(wrapper);

        UpdateWrapper<DataModelRelationshipEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(DataModelRelationshipEntity::getIsDel, System.currentTimeMillis())
                .eq(DataModelRelationshipEntity::getTargetTableId, tableId)
                    .or()
                .eq(DataModelRelationshipEntity::getSourceTableId, tableId);
        dataModelRelationshipService.update(updateWrapper);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }


    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean tableEdit(TableAttribute table, Long tableId, Long userId) {
        Requires.requireNonNull(tableId, "编号不能为空");
        Requires.requireNonNull(table, "表配置不能为空");
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        TableAttribute.verifyField(table);
        DataModelTableEntity dataModelTableEntityOld = dataModelTableService.getById(tableId);
        Requires.requireNonNull(dataModelTableEntityOld, "参数错误");
        TableFieldQuery tableFieldQuery = TableAttribute.sqlTable(table,dataModelTableEntityOld);
        DataModelTableEntity dataModelTableEntity = tableFieldQuery.getDataModelTableEntity();
        dataModelTableEntity.setStatus(DataModelTableEntity.EDIT+dataModelTableEntityOld.getStatus());
        dataModelTableService.updateById(dataModelTableEntity);

        //2.创建sql
        List<FieldQuery> fieldQuerieAdds = new ArrayList<>();
        List<DataModelAttributeEntity> dataModelAttributeEntityAddList = new ArrayList<>();
        List<FieldQuery> fieldQueries = tableFieldQuery.getFieldList();
        //判断添加时间
        if(!dataModelTableEntity.getAddDatetime().equals(dataModelTableEntityOld.getAddDatetime())){
            if(dataModelTableEntity.getAddDatetime().equals(BooleanKey.TRUE.getCode())){
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    if (dataModelAttributeEntity.getDbName().equals(SqlFieldKey.ADDTIME.getKey())) {
                        dataModelAttributeEntity.setTableId(tableId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                        dataModelAttributeEntityAddList.add(dataModelAttributeEntity);
                        //新增
                        fieldQuerieAdds.add(fieldQuery);
                    }
                }
            }else {
                dataModelTableService.deleteField(new FieldDeleteQuery(dataModelTableEntity.getDbName(), SqlFieldKey.ADDTIME.getKey()));
            }
        }
        //判断修改时间
        if(!dataModelTableEntity.getEditDatetime().equals(dataModelTableEntityOld.getEditDatetime())){
            if(dataModelTableEntity.getEditDatetime().equals(BooleanKey.TRUE.getCode())){
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    if (dataModelAttributeEntity.getDbName().equals(SqlFieldKey.EDITTIME.getKey())) {
                        dataModelAttributeEntity.setTableId(tableId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                        dataModelAttributeEntityAddList.add(dataModelAttributeEntity);
                        //新增
                        fieldQuerieAdds.add(fieldQuery);
                    }
                }
            }else {
                dataModelTableService.deleteField(new FieldDeleteQuery(dataModelTableEntity.getDbName(), SqlFieldKey.EDITTIME.getKey()));
            }
        }
        //判断添加者
        if(!dataModelTableEntity.getAddOperator().equals(dataModelTableEntityOld.getAddOperator())){
            if(dataModelTableEntity.getAddOperator().equals(BooleanKey.TRUE.getCode())){
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    if (dataModelAttributeEntity.getDbName().equals(SqlFieldKey.ADDUSER.getKey())) {
                        dataModelAttributeEntity.setTableId(tableId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                        dataModelAttributeEntityAddList.add(dataModelAttributeEntity);
                        //新增
                        fieldQuerieAdds.add(fieldQuery);
                    }
                }
            }else {
                dataModelTableService.deleteField(new FieldDeleteQuery(dataModelTableEntity.getDbName(), SqlFieldKey.ADDUSER.getKey()));
            }
        }
        //判断添加时间
        if(!dataModelTableEntity.getEditOperator().equals(dataModelTableEntityOld.getEditOperator())){
            if(dataModelTableEntity.getEditOperator().equals(BooleanKey.TRUE.getCode())){
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    if (dataModelAttributeEntity.getDbName().equals(SqlFieldKey.EDITUSER.getKey())) {
                        dataModelAttributeEntity.setTableId(tableId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                        dataModelAttributeEntityAddList.add(dataModelAttributeEntity);
                        //新增
                        fieldQuerieAdds.add(fieldQuery);
                    }
                }
            }else {
                dataModelTableService.deleteField(new FieldDeleteQuery(dataModelTableEntity.getDbName(), SqlFieldKey.EDITUSER.getKey()));
            }
        }
        //判断删除
        if(!dataModelTableEntity.getSoftDel().equals(dataModelTableEntityOld.getSoftDel())){
            if(dataModelTableEntity.getSoftDel().equals(BooleanKey.TRUE.getCode())){
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    if (dataModelAttributeEntity.getDbName().equals(SqlFieldKey.ISDEL.getKey())) {
                        dataModelAttributeEntity.setTableId(tableId);
                        dataModelAttributeEntity.setVersionId(versionId);
                        dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                        dataModelAttributeEntityAddList.add(dataModelAttributeEntity);
                        //新增
                        fieldQuerieAdds.add(fieldQuery);
                    }
                }
            }else {
                dataModelTableService.deleteField(new FieldDeleteQuery(dataModelTableEntityOld.getDbName(), SqlFieldKey.ISDEL.getKey()));
            }
        }
        dataModelTableService.addField(new TableFieldQuery(fieldQuerieAdds));
        dataModelAttributeService.saveBatch(dataModelAttributeEntityAddList);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean fieldDelete(long fieldId, Long userId) {
        DataModelAttributeEntity dataModelAttributeEntityListOld = dataModelAttributeService.getById(fieldId);
        Requires.requireNonNull(dataModelAttributeEntityListOld, "参数错误");
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        DataModelTableEntity dataModelTableEntity = dataModelTableService.getById(dataModelAttributeEntityListOld.getTableId());
        if(dataModelAttributeEntityListOld.getDbNumber() == 1){
            FieldDeleteQuery fieldDeleteQuery =new FieldDeleteQuery( dataModelTableEntity.getDbName(),
                    dataModelAttributeEntityListOld.getDbName());
            dataModelTableService.deleteField(fieldDeleteQuery);
        }else{
            for (int i = 1; i< dataModelAttributeEntityListOld.getDbNumber();i++){
                FieldDeleteQuery fieldDeleteQuery =new FieldDeleteQuery( dataModelTableEntity.getDbName(),
                        dataModelAttributeEntityListOld.getDbName()+ Convert.toStr(i));
                dataModelTableService.deleteField(fieldDeleteQuery);
            }
        }
        //删除
        UpdateWrapper<DataModelAttributeEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(DataModelAttributeEntity::getIsDel, DateUtils.getDate(DateUtils.DATETIME_LONG_FORMAT))
                .eq(DataModelAttributeEntity::getId, fieldId);
        dataModelAttributeService.update(updateWrapper);

        UpdateWrapper<DataModelRelationshipEntity> relationshipEntityUpdateWrapper = new UpdateWrapper<>();
        relationshipEntityUpdateWrapper.lambda()
                .set(DataModelRelationshipEntity::getIsDel, System.currentTimeMillis())
                .eq(DataModelRelationshipEntity::getTargetAttributeId, fieldId)
                .or()
                .eq(DataModelRelationshipEntity::getSourceAttributeId, fieldId);
        dataModelRelationshipService.update(relationshipEntityUpdateWrapper);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean fieldAddV2(IParentModelData parentModelData, Long tableId, Long userId) {
        Requires.requireNonNull(tableId, "参数不能为空");
        Requires.requireNonNull(parentModelData, "字段内容不能为空");
        Requires.requireNonBlank(parentModelData.getBeanType(), "beanType值不能为空");
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        DataModelTableEntity dataModelTableEntity = dataModelTableService.getById(tableId);
        Requires.requireNonNull(dataModelTableEntity, "参数错误");
        List<DataModelAttributeEntity> dataModelAttributeEntityList = new ArrayList<>();
        List<FieldQuery> fieldQueries = null;
        try {
            BasicAttribute basicAttribute = getByBeanType(parentModelData.getBeanType());
            basicAttribute.verifyFieldV2(parentModelData.getAttributes());
            parentModelData.setTableName(dataModelTableEntity.getDbName());
            fieldQueries = basicAttribute.sqlField(parentModelData,null);
            for (FieldQuery fieldQuery :
                    fieldQueries) {
                DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                if(dataModelAttributeEntity != null){
                    dataModelAttributeEntity.setTableId(tableId);
                    dataModelAttributeEntity.setAddUser(userId);
                    dataModelAttributeEntity.setVersionId(versionId);
                    dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                    dataModelAttributeEntityList.add(dataModelAttributeEntity);
                }
            }
        } catch (ClassNotFoundException e) {
            log.error("json未获得beanType，{}", e);
            throw new ModelException("json未获得beanType值，" + parentModelData);
        }
        TableFieldQuery tableFieldQuery = new TableFieldQuery(dataModelTableEntity.getDbName(), fieldQueries);
        tableFieldQuery.setTableName(dataModelTableEntity.getDbName());
        dataModelAttributeService.saveBatch(dataModelAttributeEntityList);
        dataModelTableService.addField(tableFieldQuery);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean fieldsAdd(List<IParentModelData> parentModelDatas, Long tableId, Long userId) {
        Requires.requireNonNull(tableId, "参数不能为空");
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        DataModelTableEntity dataModelTableEntity = dataModelTableService.getById(tableId);
        Requires.requireNonNull(dataModelTableEntity, "参数错误");
        List<DataModelAttributeEntity> dataModelAttributeEntityList = new ArrayList<>();
        List<FieldQuery> fieldQueries = null;
        for (IParentModelData parentModelData:
                parentModelDatas
             ) {
            Requires.requireNonNull(parentModelData, "字段内容不能为空");
            Requires.requireNonBlank(parentModelData.getBeanType(), "beanType值不能为空");
            try {
                BasicAttribute basicAttribute = getByBeanType(parentModelData.getBeanType());
                basicAttribute.verifyField(parentModelData.getAttributes());
                parentModelData.setTableName(dataModelTableEntity.getDbName());
                fieldQueries = basicAttribute.sqlField(parentModelData,null);
                for (FieldQuery fieldQuery :
                        fieldQueries) {
                    DataModelAttributeEntity dataModelAttributeEntity = fieldQuery.getDataModelAttributeEntity();
                    dataModelAttributeEntity.setTableId(tableId);
                    dataModelAttributeEntity.setAddUser(userId);
                    dataModelAttributeEntity.setVersionId(versionId);
                    dataModelAttributeEntity.setStatus(DataModelAttributeEntity.ADD);
                    dataModelAttributeEntityList.add(dataModelAttributeEntity);
                }
            } catch (ClassNotFoundException e) {
                log.error("json未获得beanType，{}", e);
                throw new ModelException("json未获得beanType值，" + parentModelData);
            }
        }
        TableFieldQuery tableFieldQuery = new TableFieldQuery(dataModelTableEntity.getDbName(), fieldQueries);
        tableFieldQuery.setTableName(dataModelTableEntity.getDbName());
        dataModelAttributeService.saveBatch(dataModelAttributeEntityList);
        dataModelTableService.addField(tableFieldQuery);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }


    private BasicAttribute getByBeanType(String beanType) throws ClassNotFoundException {
        Requires.requireNonBlank(beanType, "bean type is null");
        Map<String, BeanTypeKey> enumMap = EnumUtil.getEnumMap(BeanTypeKey.class);
        Class<?> classes = Class.forName(enumMap.get(beanType.toUpperCase()).getBean());
        return (BasicAttribute) ReflectUtil.newInstance(classes);
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean fieldEditV2(IParentModelData parentModelData, long fieldId, Long userId) {
        //缺少存在关联关系
        //存在值
        Requires.requireNonNull(fieldId, "编号不能为空");
        Requires.requireNonNull(parentModelData, "字段内容不能为空");

        Requires.requireNonBlank(parentModelData.getBeanType(), "beanType值不能为空");

        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        QueryWrapper<DataModelAttributeEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DataModelAttributeEntity::getId, fieldId);
        List<DataModelAttributeEntity> dataModelAttributeEntityListOld = dataModelAttributeService.list(queryWrapper);
        if (dataModelAttributeEntityListOld.size() == 0) {
            throw new ModelException("fieldTypeId错误");
        }
        Requires.requireTrue(dataModelAttributeEntityListOld.size() == 1 , String.format("fieldId : {} not found", fieldId));
        DataModelAttributeEntity dataModelAttributeEntityOld = dataModelAttributeEntityListOld.get(0);
        List<DataModelAttributeEntity> dataModelAttributeEntityList = new ArrayList<>();
        List<FieldQuery> fieldQueries = null;
        try {
            BasicAttribute basicAttribute = getByBeanType(parentModelData.getBeanType());
            basicAttribute.verifyFieldV2(parentModelData.getAttributes());
            fieldQueries = basicAttribute.sqlField(parentModelData,dataModelAttributeEntityOld);
            for (FieldQuery fieldQuery :
                    fieldQueries) {
                DataModelAttributeEntity dataModelAttributeEntity1 = fieldQuery.getDataModelAttributeEntity();
                if(dataModelAttributeEntity1 != null){
                    dataModelAttributeEntity1.setTableId(dataModelAttributeEntityOld.getTableId());
                    dataModelAttributeEntity1.setVersionId(versionId);
                    dataModelAttributeEntity1.setAddUser(userId);
                    dataModelAttributeEntity1.setUpdateUser(userId);
                    dataModelAttributeEntity1.setStatus(dataModelAttributeEntityOld.getStatus()+DataModelAttributeEntity.EDIT);
                    dataModelAttributeEntityList.add(dataModelAttributeEntity1);
                }
            }
        } catch (ClassNotFoundException e) {
            log.error("json未获得beanType，{}", e);
            throw new ModelException("json未获得beanType值，" + parentModelData);
        }
        DataModelTableEntity dataModelTableEntity = dataModelTableService.getById(dataModelAttributeEntityOld.getTableId());
        //执行sql ，
        TableFieldQuery tableFieldQuery = new TableFieldQuery(dataModelTableEntity.getDbName(), fieldQueries);
        dataModelTableService.editField(tableFieldQuery);
        UpdateWrapper<DataModelAttributeEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(DataModelAttributeEntity::getIsDel, DateUtils.getDate(DateUtils.DATETIME_LONG_FORMAT))
                .eq(DataModelAttributeEntity::getId, fieldId);
        dataModelAttributeService.update(updateWrapper);
        dataModelAttributeService.saveBatch(dataModelAttributeEntityList);
        dataModelVersionService.hasEdit(versionId);
        return true;
    }

    @Override
    public List<ModelDataJsonListResponse> tableListV2(Long userId) {
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        return getModelDataList(userId, versionId);
    }

    @Override
    public List<ModelDataJsonListResponse> tablePublishListV2(Long userId) {
        Long versionId = dataModelVersionService.getModelVersionPublish(userId);
        if(versionId == null){
            return new ArrayList<>();
        }
        return getModelDataList(userId, versionId);
    }

    private List<ModelDataJsonListResponse> getModelDataList(Long userId, Long versionId){
        List<ModelDataJsonTableQuery> dataJsonTableQueries = dataModelTableService.tableJsonAll(userId, versionId);

        List<String> rels = new ArrayList<>();
        rels.add(BeanTypeKey.SWITCH.getKey());
        rels.add(BeanTypeKey.EMAIL.getKey());
        rels.add(BeanTypeKey.PHONE.getKey());
        rels.add(BeanTypeKey.TELEPHONE.getKey());
        rels.add(BeanTypeKey.NUMBER.getKey());
        rels.add(BeanTypeKey.AGE.getKey());
        rels.add(BeanTypeKey.IDCARD.getKey());
        rels.add(BeanTypeKey.POSTCODE.getKey());
        rels.add(BeanTypeKey.MONEY.getKey());
        rels.add(BeanTypeKey.UNKNOWNNUMBER.getKey());
        rels.add(BeanTypeKey.TEXT.getKey());
        rels.add(BeanTypeKey.DATETIME.getKey());
        rels.add(BeanTypeKey.YEAR.getKey());
        rels.add(BeanTypeKey.MONTH.getKey());
        rels.add(BeanTypeKey.ID.getKey());
        rels.add(BeanTypeKey.TEXT.getKey());
        List<ModelDataJsonListResponse> modelDataJsonListResponses = new ArrayList<>();
        for (ModelDataJsonTableQuery table :
                dataJsonTableQueries) {
            List<JSONObject> modelDataJsonResponses = new ArrayList<>();
            if(table.getFields() != null){
                for (ModelDataJsonAttributeQuery field :
                        table.getFields()) {
                    if(field.getBeanType() != null){
                        JSONObject jsonObject = null;
                        BeanTypeKey beanTypeKey = null;
                        JSONObject jsonObjectBean = null;
                        Meta meta = null;
                        try {
                            Map<String, BeanTypeKey> enumMap = EnumUtil.getEnumMap(BeanTypeKey.class);
                            beanTypeKey = enumMap.get(field.getBeanType().toUpperCase());
                            Class<?> classes = Class.forName(beanTypeKey.getBean());
                            BasicAttribute basicAttribute = (BasicAttribute) ReflectUtil.newInstance(classes);
                            jsonObject = basicAttribute.getAttribute(field);
                            jsonObjectBean = basicAttribute.getAttributeStyle(field);
                            meta = basicAttribute.getMeta(field);
                        } catch (ClassNotFoundException e) {
                            log.error("json未获得beanType,{}", e);
                            throw new ModelException("json未获得beanType值，" + field.getBeanType());
                        }
                        if(jsonObjectBean != null){
                            JSONObject jsonObject1 = new JSONObject();
                            jsonObject1.set("id",field.getId());
                            jsonObject1.set("name",beanTypeKey.getName());
                            jsonObject1.set("desc", beanTypeKey.getDesc());
                            jsonObject1.set("beanType", field.getBeanType());
                            jsonObject1.set("addTime",field.getAddTime());
                            jsonObject1.set("updateTime",field.getUpdateTime());
                            Boolean relationshipUse = false;
                            if(rels.contains(field.getBeanType())){
                                relationshipUse = true;
                            }
                            jsonObject1.set("relationshipUse", relationshipUse);
                            jsonObject1.set("attributes",jsonObject);
                            jsonObject1.set("editStyle", jsonObjectBean);
                            jsonObject1.set("meta",meta == null ? new JSONObject() : meta);
                            modelDataJsonResponses.add(jsonObject1);
                        }
                    }
                }

            }
            modelDataJsonListResponses.add( new ModelDataJsonListResponse(table.getAddTime(), table.getUpdateTime(), new JSONObject(TableAttribute.getAttribute(table)), modelDataJsonResponses));
        }
        return modelDataJsonListResponses;
    }
    @Override
    public ModelDataJsonListResponse tableInfo(Long tableId) {
        ModelDataJsonTableQuery table = dataModelTableService.tableJsonInfo(tableId);
        List<JSONObject> modelDataJsonResponses = new ArrayList<>();
        for (ModelDataJsonAttributeQuery field :
                table.getFields()) {
            if(field.getBeanType() != null){
                JSONObject jsonObject = null;
                BeanTypeKey beanTypeKey = null;
                Meta meta = null;
                try {
                    Map<String, BeanTypeKey> enumMap = EnumUtil.getEnumMap(BeanTypeKey.class);
                    beanTypeKey = enumMap.get(field.getBeanType().toUpperCase());
                    Class<?> classes = Class.forName(beanTypeKey.getBean());
                    BasicAttribute basicAttribute = (BasicAttribute) ReflectUtil.newInstance(classes);
                    jsonObject = basicAttribute.getAttribute(field);
                    meta = basicAttribute.getMeta(field);
                } catch (ClassNotFoundException e) {
                    log.error("json未获得beanType，{}", e);
                    throw new ModelException("json未获得beanType值，" + field.getBeanType());
                }
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.set("id",field.getId());
                jsonObject1.set("name",beanTypeKey.getName());
                jsonObject1.set("desc", beanTypeKey.getDesc());
                jsonObject1.set("beanType", field.getBeanType());
                jsonObject1.set("addTime",field.getAddTime());
                jsonObject1.set("updateTime",field.getUpdateTime());
                jsonObject1.set("attributes",jsonObject);
                jsonObject1.set("meta",meta == null ? new JSONObject() : meta);
                modelDataJsonResponses.add(jsonObject1);
            }
        }
        return new ModelDataJsonListResponse(table.getAddTime(), table.getUpdateTime(), new JSONObject(TableAttribute.getAttribute(table)), modelDataJsonResponses);
    }

    @Override
    public List<ModelVersionResponse> getVersionList(Long userId) {
        QueryWrapper<DataModelVersionEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(DataModelVersionEntity::getAddUser, userId)
            .in(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.PUBLISH, DataModelVersionEntity.RECORD)
            .orderByAsc(DataModelVersionEntity::getId);
        return dataModelVersionService.list(wrapper).stream().map(entity->{
            ModelVersionResponse modelVersionResponse = new ModelVersionResponse();
            BeanUtils.copyProperties(entity, modelVersionResponse);
            return modelVersionResponse;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean publish(Long userId) {
        //判断发布版本数据是否有变化
        Long versionId = dataModelVersionService.getModelVersionEdit(userId);
        QueryWrapper<DataModelVersionEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(DataModelVersionEntity::getAddUser, userId)
                .eq(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.EDIT)
                .orderByDesc(DataModelVersionEntity::getUpdateTime);
        List<DataModelVersionEntity> dataModelVersionEntitys = dataModelVersionService.list(wrapper);
        if(dataModelVersionEntitys.size() == 0){
            throw new ModelException("发布数据版本不存在,不能发布");
        }
        if(dataModelVersionEntitys.size() > 1){
            throw new ModelException("发布版本存在多个,不能发布");
        }
        if(!dataModelVersionEntitys.get(0).getHasEdit()){
            throw new ModelException("当前版本数据未更改,不允许发布");
        }
        //只要编辑版本，赋值模型，字段数据
        UpdateWrapper<DataModelVersionEntity> updateWrapperPulbish = new UpdateWrapper<>();
        updateWrapperPulbish.lambda()
                .set(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.RECORD)
                .eq(DataModelVersionEntity::getAddUser, userId)
                .eq(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.PUBLISH);
        dataModelVersionService.update(updateWrapperPulbish);
        //修改编辑状态为发布状态
        UpdateWrapper<DataModelVersionEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.PUBLISH)
                .eq(DataModelVersionEntity::getId, versionId)
                .eq(DataModelVersionEntity::getIsDel, Constants.NOT_DEL_TAG)
                .eq(DataModelVersionEntity::getAddUser, userId)
                .eq(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.EDIT);
        dataModelVersionService.update(updateWrapper);
        //创建编辑版本
        DataModelVersionEntity dataModelVersionEntity = new DataModelVersionEntity();
        dataModelVersionEntity.setAddUser(userId);
        dataModelVersionEntity.setName(DateUtils.getDate(DateUtils.DATETIME_FORMAT));
        dataModelVersionEntity.setCurrentVersion(DataModelVersionEntity.EDIT);
        dataModelVersionService.save(dataModelVersionEntity);
        //赋值数据模型
        this.copyModelData(dataModelVersionEntity.getId(), versionId, userId);
        return true;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean rollback(Long userId, Long versionId) {
        Long publishVersionId = dataModelVersionService.getModelVersionPublish(userId);
        if(publishVersionId.equals(versionId)){
            throw new ModelException("不能回退到当前版本");
        }
        //删除编辑发布的版本
        Long versionNotPublishId = dataModelVersionService.getModelVersionEdit(userId);
        dataModelTableService.deleteTable(userId, versionNotPublishId);
        dataModelAttributeService.deleteAttribute(userId, versionNotPublishId);
        dataModelRelationshipService.deleteRelationship(userId, versionNotPublishId);
        //删除上一个编辑版本数据
        UpdateWrapper<DataModelVersionEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(DataModelVersionEntity::getIsDel, System.currentTimeMillis())
                .eq(DataModelVersionEntity::getId, versionNotPublishId)
                .eq(DataModelVersionEntity::getAddUser, userId)
                .eq(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.EDIT);
        dataModelVersionService.update(updateWrapper);
        //发布版本改成历史版本
        UpdateWrapper<DataModelVersionEntity> updateWrapperPulbish = new UpdateWrapper<>();
        updateWrapperPulbish.lambda()
                .set(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.RECORD)
                .eq(DataModelVersionEntity::getAddUser, userId)
                .eq(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.PUBLISH);
        dataModelVersionService.update(updateWrapperPulbish);
        //回退版本改成发布
        UpdateWrapper<DataModelVersionEntity> updateWrapperNew = new UpdateWrapper<>();
        updateWrapperNew.lambda()
                .set(DataModelVersionEntity::getCurrentVersion, DataModelVersionEntity.PUBLISH)
                .set(DataModelVersionEntity::getHasEdit, false)
                .eq(DataModelVersionEntity::getId, versionId)
                .eq(DataModelVersionEntity::getAddUser, userId);
        dataModelVersionService.update(updateWrapperNew);
        //添加新的编辑版本数据
        DataModelVersionEntity dataModelVersionEntity = new DataModelVersionEntity();
        dataModelVersionEntity.setAddUser(userId);
        dataModelVersionEntity.setPId(versionId);
        dataModelVersionEntity.setName(DateUtils.getDate(DateUtils.DATETIME_FORMAT));
        dataModelVersionEntity.setCurrentVersion(DataModelVersionEntity.EDIT);
        dataModelVersionService.save(dataModelVersionEntity);
        this.copyModelData(dataModelVersionEntity.getId(),versionId,userId);
        return true;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean order(List<ModelOrderRequest> modelOrderRequests, UserInfo userInfo) {
        Long versionId = dataModelVersionService.getModelVersionEdit(userInfo.getId());
        List<ModelOrder> tableModelOrder = new ArrayList<>();
        List<ModelOrder> attributeModelOrder = new ArrayList<>();
        int tableOrder = 1;
        for (ModelOrderRequest request: modelOrderRequests){
            ModelOrder modelOrderTable = new ModelOrder();
            modelOrderTable.setId(request.getId());
            modelOrderTable.setOrder(tableOrder);
            tableModelOrder.add(modelOrderTable);
            tableOrder++;

            int attributeOrder = 1;
            for(Long attrRequest: request.getFields()){
                ModelOrder modelOrderAttribute = new ModelOrder();
                modelOrderAttribute.setId(attrRequest);
                modelOrderAttribute.setOrder(attributeOrder);
                attributeModelOrder.add(modelOrderAttribute);
                attributeOrder++;
            }
        }
        if(tableModelOrder.size() > 0){
            dataModelTableService.order(tableModelOrder, versionId, userInfo.getId());
        }
        if(attributeModelOrder.size() > 0){
            dataModelAttributeService.order(attributeModelOrder, versionId, userInfo.getId());
        }
        dataModelVersionService.hasEdit(versionId);
        return true;
    }

    /**
     * 赋值模型数据
     * @param newVersionId 原始
     * @param sourceVersionId 来自
     * @param userId
     */
    private void copyModelData(Long newVersionId, Long sourceVersionId, Long userId){
        QueryWrapper<DataModelTableEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DataModelTableEntity::getVersionId, sourceVersionId)
                .eq(DataModelTableEntity::getAddUser, userId);
        List<DataModelTableEntity> dataModelTableEntities = dataModelTableService.list(queryWrapper);
        if(dataModelTableEntities.size() == 0){
            return;
        }
        QueryWrapper<DataModelAttributeEntity> dataModelAttributeEntityQueryWrapper = new QueryWrapper<>();
        dataModelAttributeEntityQueryWrapper.lambda()
                .eq(DataModelAttributeEntity::getVersionId, sourceVersionId)
                .eq(DataModelAttributeEntity::getAddUser, userId);
        List<DataModelAttributeEntity> dataModelAttributeEntities = dataModelAttributeService.list(dataModelAttributeEntityQueryWrapper);

        QueryWrapper<DataModelRelationshipEntity> dataModelRelationshipEntityQueryWrapper = new QueryWrapper<>();
        dataModelRelationshipEntityQueryWrapper.lambda()
                .eq(DataModelRelationshipEntity::getAddUser, userId)
                .eq(DataModelRelationshipEntity::getVersionId, sourceVersionId);
        List<DataModelRelationshipEntity> dataModelRelationshipEntities = dataModelRelationshipService.list(dataModelRelationshipEntityQueryWrapper);
        List<DataModelTableEntity> dataModelTableEntityNewList = new ArrayList<>();
        for (DataModelTableEntity tabelEntity :
                dataModelTableEntities) {
            DataModelTableEntity entity = new DataModelTableEntity();
            BeanUtils.copyProperties(tabelEntity, entity);
            entity.setVersionId(newVersionId);
            entity.setSourceId(tabelEntity.getId());
            entity.setAddUser(userId);
            dataModelTableEntityNewList.add(entity);
        }
        if(dataModelTableEntityNewList.size() > 0){
            dataModelTableService.saveBatch(dataModelTableEntityNewList, 50);
        }

        //模型字段
        //原始id， 新id
        Map<Long, Long> tableMap = dataModelTableEntityNewList.stream().collect(Collectors.toMap(DataModelTableEntity::getSourceId, DataModelTableEntity::getId, (key1, key2) -> key2));

        List<DataModelAttributeEntity> dataModelAttributeEntityNewList = new ArrayList<>();
        for (DataModelAttributeEntity entity:
            dataModelAttributeEntities){
            DataModelAttributeEntity dataModelAttributeEntity = new DataModelAttributeEntity();
            BeanUtils.copyProperties(entity, dataModelAttributeEntity);
            dataModelAttributeEntity.setVersionId(newVersionId);
            dataModelAttributeEntity.setTableId(tableMap.get(entity.getTableId()));
            dataModelAttributeEntity.setAddUser(userId);
            dataModelAttributeEntity.setSourceId(entity.getId());
            dataModelAttributeEntityNewList.add(dataModelAttributeEntity);
        }
        if(dataModelAttributeEntityNewList.size() > 0){
            dataModelAttributeService.saveBatch(dataModelAttributeEntityNewList, 50);
        }
        //原始id， 新id
        Map<Long, Long> attributeMap = dataModelAttributeEntityNewList.stream().collect(Collectors.toMap(DataModelAttributeEntity::getSourceId, DataModelAttributeEntity::getId, (key1, key2) -> key2));

        //模型关系
        List<DataModelRelationshipEntity> dataModelRelationshipNewList = new ArrayList<>();
        for (DataModelRelationshipEntity entity:
                dataModelRelationshipEntities){
            DataModelRelationshipEntity dataModelRelationshipEntity = new DataModelRelationshipEntity();
            dataModelRelationshipEntity.setVersionId(newVersionId);
            dataModelRelationshipEntity.setAddUser(userId);
            dataModelRelationshipEntity.setSourceType(entity.getSourceType());
            dataModelRelationshipEntity.setTargetType(entity.getTargetType());
            dataModelRelationshipEntity.setSourceTableId(tableMap.get(entity.getSourceTableId()));
            dataModelRelationshipEntity.setSourceAttributeId(attributeMap.get(entity.getSourceAttributeId()));
            dataModelRelationshipEntity.setTargetTableId(tableMap.get(entity.getTargetTableId()));
            dataModelRelationshipEntity.setTargetAttributeId(attributeMap.get(entity.getTargetAttributeId()));
            dataModelRelationshipNewList.add(dataModelRelationshipEntity);
        }
        if(dataModelAttributeEntityNewList.size() > 0){
            dataModelRelationshipService.saveBatch(dataModelRelationshipNewList, 50);
        }
    }

    /**
     * 校验传参
     *
     * @param modelDataAddRequest
     * @return
     */
    public void verifyModelDataAddRequest(ModelDataAddRequest modelDataAddRequest) {
        TableAttribute.verifyField(modelDataAddRequest.getTable());
        if(modelDataAddRequest.getFields() != null && modelDataAddRequest.getFields().size() != 0){
            for (IParentModelData parentModelData :
                    modelDataAddRequest.getFields()) {
                if (null == parentModelData) {
                    throw new ModelException("json传值格式错误，" + parentModelData);
                }
                Requires.requireNonBlank(parentModelData.getBeanType(), "beanType值不能为空");
                try {
                    BasicAttribute basicAttribute = getByBeanType(parentModelData.getBeanType());
                    basicAttribute.verifyField(parentModelData.getAttributes());
                } catch (ClassNotFoundException e) {
                    log.error("json未获得beanType，{}", e);
                    throw new ModelException("json未获得beanType值，" + parentModelData);
                }
            }

        }
    }
}
